#--
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
#
# For licensing information see the LICENSE.md file in the project root.
#++

module SoftLayer
  #
  # This class allows you to order a Firewall for a server
  #
  class ServerFirewallOrder
    # The server that you are ordering the firewall for.
    attr_reader :server

    ##
    # Create a new order for the given server
    def initialize (server)
      @server = server

      raise ArgumentError, "Server does not have an active Public interface" if server.firewall_port_speed == 0
    end

    ##
    # Calls the SoftLayer API to verify that the template provided by this order is valid
    # This routine will return the order template generated by the API or will throw an exception
    #
    # This routine will not actually create a Bare Metal Instance and will not affect billing.
    #
    # If you provide a block, it will receive the order template as a parameter and
    # the block may make changes to the template before it is submitted.
    def verify()
      order_template = firewall_order_template
      order_template = yield order_template if block_given?

      server.softlayer_client[:Product_Order].verifyOrder(order_template)
    end

    ##
    # Calls the SoftLayer API to place an order for a new server based on the template in this
    # order. If this succeeds then you will be billed for the new server.
    #
    # If you provide a block, it will receive the order template as a parameter and
    # the block may make changes to the template before it is submitted.
    def place_order!()
      order_template = firewall_order_template
      order_template = yield order_template if block_given?

      server.softlayer_client[:Product_Order].placeOrder(order_template)
    end

    protected

    ##
    # Returns a hash of the creation options formatted to be sent *to*
    # the SoftLayer API for either verification or completion
    def firewall_order_template
      client = server.softlayer_client
      additional_products_package = SoftLayer::ProductPackage.additional_products_package(client)

      template = {
          'complexType' => 'SoftLayer_Container_Product_Order_Network_Protection_Firewall',
          'quantity' => 1,
          'packageId' => additional_products_package.id
        }

      if @server.service.service_name == "SoftLayer_Virtual_Guest"
        template['virtualGuests'] = [{'id' => @server.id}]
      else
        template['hardware'] = [{'id' => @server.id}]
      end

      expected_description = "#{@server.firewall_port_speed}Mbps Hardware Firewall"
      firewall_items = additional_products_package.items_with_description(expected_description)

      raise "Could not find a price item matching the description '#{expected_description}'" if firewall_items.empty?

      firewall_item = firewall_items[0]

      template['prices'] = [{ 'id' => firewall_item.price_id }] if firewall_item.respond_to?(:price_id)

      template
    end
  end # class ServerFirewallOrder
end # module SoftLayer
